home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / 2m30src.zip / 2M-INFDT.C < prev    next >
C/C++ Source or Header  |  1995-03-06  |  15KB  |  488 lines

  1.  
  2. /*───────────────────────────────────────────────────────────────────\
  3. │                                                                    │
  4. │     FDTR 3.0  -   Módulo de test de velocidad de disquetes.        │
  5. │                                                                    │
  6. │                (C) 1994-1995  Ciriaco García de Celis              │
  7. │                                                                    │
  8. \───────────────────────────────────────────────────────────────────*/
  9.  
  10. #include <conio.h>
  11. #include <alloc.h>
  12. #include <dos.h>
  13. #include "2m-info.h"
  14.  
  15.  
  16. #define MAXS     46       /* como máximo, 46 sectores de 512 bytes */
  17. #define BMAX  (MAXS*512L)
  18. #define RD        2
  19. #define WR        3
  20.  
  21. #define CX       12       /* color para pantalla de "memoria insuficiente" */
  22. #define CFX       0       /* color de fondo para "memoria insuficiente" */
  23. #define CP       15       /* color principal */
  24. #define CFP       0       /* color de fondo principal */
  25. #define C3D      14       /* color para el marco 3D */
  26. #define C3M      10       /* color para la banda del marco 3D */
  27. #define CFC       3       /* color de fondo central */
  28. #define CB        4       /* color para botones de unidades */
  29. #define CTB      15       /* color para tinta de botones de unidades */
  30. #define CT       15       /* color para tinta del test */
  31. #define CFT       1       /* color de fondo para el test */
  32.  
  33.  
  34. extern   int  Tecla (void);
  35. extern   int  TipoDrive (int);
  36. extern   int  Hay2M3 (void);
  37. extern   int  sp;
  38. extern   void CursorOff (void);
  39. extern   void BrilloOn (void);
  40. extern   void ventana (int, int, int, int, int, int, int);
  41. extern   void v3dg (int, int, int, int, int, int, int, int, int);
  42. extern   void v3df (int, int, int, int, int, int, int, int);
  43. extern   void boton (int, int, int, int, int, int, char *);
  44. extern   void interrupt NuevaInt24 (void);
  45. extern   char *dec2str (unsigned);
  46. extern   char *dec3str (unsigned);
  47. extern   char *dec5str (unsigned);
  48. extern   char *dec2strq (unsigned);
  49. extern   char *dec3strq (unsigned);
  50. extern   char *dec5strq (unsigned);
  51. extern   unsigned long tiempo (void);
  52.  
  53.  
  54. char     *Memoria (char **);
  55. void     PruebaBios (int, unsigned char *, int),
  56.          PruebaDos (int, unsigned char *, int);
  57. int      Es2mgui (int),
  58.          biosdsk (int, int, int, int, int, int, unsigned char *),
  59.          EvaluaBiosIO (unsigned, char *, unsigned,
  60.                        unsigned, unsigned, unsigned, unsigned),
  61.          EvaluaDosIO (unsigned, char *, unsigned, unsigned,
  62.                       unsigned, unsigned),
  63.          ObtenerInfo (unsigned, struct dfree *,
  64.                       unsigned *, unsigned *, unsigned *, unsigned *);
  65.  
  66.  
  67. void fdtr (int autotest, int drive)
  68. {
  69.   char unidad[4],
  70.        base,
  71.        btxt[]=" A: ",
  72.        *bloque, *buffer, disco;
  73.   void interrupt (*ViejaInt24) (void);
  74.   int  i, opc;
  75.  
  76.  
  77.   if ((bloque=Memoria (&buffer))!=NULL) {
  78.     if (TipoDrive(0)!=-1) {
  79.         unidad[0]=TipoDrive(0);  /* !=0 si existe */
  80.         unidad[1]=TipoDrive(1);  /* !=0 si existe */
  81.         }
  82.       else {
  83.         unidad[0]=1;
  84.         if (peekb(0x40, 0x10) >> 6) unidad[1]=1; else unidad[1]=0;
  85.         }
  86.  
  87.     unidad[2]=unidad[3]=0;  /* supuestas no unidades 2MGUI */
  88.     disco=2;
  89.     for (i=2; i<26; i++)
  90.       if (Es2mgui(i)) {
  91.         if (disco==2) base=i;  /* letra inicial unidades 2MGUI */
  92.         unidad [disco++] = 1;
  93.         }
  94.  
  95.     textbackground (CFP); textcolor (CP); clrscr();
  96.     v3dg (1, 1, 80, 25, 1, 4, C3D, CFP, C3M);
  97.     textbackground (CFP); textcolor (CP);
  98.     gotoxy (16,7);
  99.     if (sp)
  100.         cputs("CALCULO DE LA VELOCIDAD DE TRANSFERENCIA ABSOLUTA");
  101.       else
  102.         cputs("   ABSOLUTE FLOPPY DISK DATA TRANSFER RATE CALC");
  103.     window (18, 9, 62, 19); textbackground (CFC); clrscr();
  104.     v3df (2, 1, 43, 11, 1, 1, CFC+8, CFC);
  105.     textcolor (CP);
  106.     gotoxy (6,4);
  107.     if (sp) cputs("Pulsa la letra de la unidad elegida");
  108.       else cputs("Press drive-key to choose one drive");
  109.     for (i=0; i<4; i++) {
  110.       if (i<2) btxt[1]=i+'A'; else btxt[1]=i+'A'+base-2;
  111.       if (unidad[i]) boton (i*8+8, 6, CB,CTB,CP,CFC, btxt);
  112.       }
  113.     boton (8, 8, CB,CTB,CP,CFC, sp?"INTRO":"ENTER");
  114.     if (sp) cputs(" Salir"); else cputs(" Exit");
  115.     window (1,1,80,25);
  116.  
  117.     ViejaInt24=getvect(0x24);
  118.     setvect (0x24, NuevaInt24);      /* evitar error crítico */
  119.     for (;;) {
  120.       CursorOff();
  121.       if (!autotest) opc = Tecla(); else opc=drive+'A';
  122.       if ((opc==27) || (opc==13) || (opc==0x2D00)) break;
  123.       disco = (opc | ' ') - 'a';
  124.       if (((disco>=0) && (disco<2) && (unidad[disco])) ||
  125.          ((disco-base>=0) && (disco-base<2) && (unidad[disco-base]))) {
  126.         ventana (ABRIR, 16, 9, 65, 19, CT, CFT);
  127.         gotoxy (14,1); if (sp) cputs("UNIDAD "); else cputs("DRIVE ");
  128.         putch(disco+'A'); putch(':');
  129.         if (disco<2)
  130.             PruebaBios (disco, buffer, autotest);
  131.           else
  132.             PruebaDos (disco, buffer, autotest);
  133.         ventana (CERRAR, 16, 9, 65, 19, 0, 0);
  134.         }
  135.       if (autotest) break;
  136.     }
  137.     setvect (0x24, ViejaInt24);
  138.     farfree (bloque);
  139.   }
  140. }
  141.  
  142.  
  143. char *Memoria (char **buffer)
  144. {
  145.   unsigned long dir;
  146.   char     *bloque, *bf;
  147.  
  148.   *buffer=bloque=farmalloc(BMAX << 1);
  149.   bf=farmalloc(4096L);
  150.  
  151.   if ((*buffer==NULL) || (bf==NULL)) {
  152.     if (*buffer!=NULL) farfree (*buffer);
  153.     textbackground (CFX); textcolor (CX); clrscr();
  154.     gotoxy (26,12);
  155.     if (sp)
  156.         cputs ("Memoria insuficiente para FDTR");
  157.       else
  158.         cputs ("Insufficient memory for FDTR");
  159.     CursorOff();
  160.     delay (2000);
  161.     return (NULL);
  162.     }
  163.  
  164.   farfree (bf);  /* liberar bloque "de seguridad" */
  165.  
  166.   dir = ((unsigned long) FP_SEG(*buffer) <<4) + FP_OFF(*buffer);
  167.   if ( (dir>>16) != ( (dir+BMAX) >> 16) )
  168.      *buffer+=BMAX;    /* evitar buffer entre dos páginas de DMA */
  169.  
  170.   return (bloque);
  171. }
  172.  
  173.  
  174. void PruebaBios (int unidad, unsigned char *buffer, int autotest)
  175. {
  176.   struct   dfree dsk;
  177.   unsigned sectores, cabezales, cilindros, ts, acabo;
  178.  
  179.   if (sp) cputs(" Nivel BIOS"); else cputs(" BIOS access");
  180.  
  181.   acabo = ObtenerInfo (unidad, &dsk, §ores, &cabezales, &cilindros, &ts);
  182.   if (acabo) {
  183.     gotoxy (3,3); if (sp) cputs("LECTURA: "); else cputs("READ: ");
  184.     acabo = EvaluaBiosIO (RD, buffer, unidad, cilindros, sectores, cabezales, ts);
  185.     if (acabo) {
  186.       gotoxy (3,6); if (sp) cputs("ESCRITURA: "); else cputs("WRITE: ");
  187.       if (dsk.df_avail < dsk.df_total) {
  188.           gotoxy (5,7);
  189.           if (sp)
  190.               cputs("Disquete no vacío -> sin test de escritura");
  191.             else
  192.               cputs("Diskette not empty -> write test skipped");
  193.           }
  194.         else
  195.           EvaluaBiosIO (WR, buffer, unidad, cilindros, sectores, cabezales, ts);
  196.       }
  197.     }
  198.  
  199.   gotoxy (18,9);
  200.   if (!autotest || !acabo) {
  201.       if (sp) cputs("Pulsa una tecla"); else cputs(" Press any key");
  202.       CursorOff();
  203.       Tecla();
  204.       }
  205.     else {
  206.       CursorOff();
  207.       delay(2000);
  208.       }
  209. }
  210.  
  211.  
  212. void PruebaDos (int unidad, unsigned char *buffer, int autotest)
  213. {
  214.   struct   dfree dsk;
  215.   unsigned sectores, cabezales, cilindros, totsect, ts, acabo;
  216.  
  217.   if (sp) cputs("  Nivel DOS"); else cputs("  DOS access");
  218.  
  219.   acabo = ObtenerInfo (unidad, &dsk, §ores, &cabezales, &cilindros, &ts);
  220.   if (acabo) {
  221.     totsect = cilindros*cabezales*sectores;
  222.     gotoxy (3,3); if (sp) cputs("LECTURA: "); else cputs("READ: ");
  223.     acabo = EvaluaDosIO (RD, buffer, unidad, sectores, totsect, ts);
  224.     if (acabo) {
  225.       gotoxy (3,6); if (sp) cputs("ESCRITURA: "); else cputs("WRITE: ");
  226.       if (dsk.df_avail < dsk.df_total) {
  227.           gotoxy (5,7);
  228.           if (sp)
  229.               cputs("Disquete no vacío -> sin test de escritura");
  230.             else
  231.               cputs("Diskette not empty -> write test skipped");
  232.           }
  233.         else
  234.           EvaluaDosIO (WR, buffer, unidad, sectores, totsect, ts);
  235.       }
  236.     }
  237.  
  238.   gotoxy (18,9);
  239.   if (!autotest || !acabo) {
  240.       if (sp) cputs("Pulsa una tecla"); else cputs(" Press any key");
  241.       CursorOff();
  242.       Tecla();
  243.       }
  244.     else {
  245.       CursorOff();
  246.       delay(2000);
  247.       }
  248. }
  249.  
  250.  
  251. int Es2mgui (int unidad)
  252. {
  253.   unsigned char  drv[128];
  254.   union    REGS  r;
  255.   struct   SREGS s;
  256.   int      loes = 0;
  257.  
  258.   if (unidad > 1) {
  259.     r.x.ax = 0x440D; r.x.bx = unidad+1; r.x.cx = 0x860;
  260.     s.ds   = r.x.si = FP_SEG (drv);
  261.     r.x.dx = r.x.di = FP_OFF (drv); drv[0]=0;
  262.     intdosx (&r, &r, &s);
  263.     if ((!(r.x.flags & 1)) && (
  264.          (drv[6]=='2'+'M') || (drv[6]=='2'+'M'+1)
  265.          )
  266.        ) loes = 1;  /* es 2MGUI */
  267.     }
  268.  
  269.   return (loes);
  270. }
  271.  
  272.  
  273. int ObtenerInfo (unidad, dsk, sectores, cabezales, cilindros, tsector)
  274. unsigned unidad, *sectores, *cabezales, *cilindros, *tsector;
  275. struct dfree *dsk;
  276. {
  277.   int  error=0;
  278.   Boot arranque;
  279.  
  280.   getdfree (unidad+1, dsk);
  281.  
  282.   if (dsk->df_sclus==65535) {
  283.     error++;
  284.     gotoxy (11,5);
  285.     if (sp)
  286.         cputs("Error de acceso a la unidad");
  287.       else
  288.         cputs("   Error on drive access");
  289.     }
  290.   else if ((long) dsk->df_total*dsk->df_sclus>65535L) {
  291.     error++;
  292.     gotoxy (6,5);
  293.     if (sp)
  294.         cputs("Disquetes de más de 32M no soportados");
  295.       else
  296.         cputs("Diskettes above 32M can not be tested");
  297.     }
  298.  
  299.   if (!error)
  300.     if (absread (unidad, 1, 0L, &arranque)) {
  301.       error++;
  302.       gotoxy (13,5);
  303.       cputs("      Fatal ????");
  304.     }
  305.  
  306.   if (!error) {
  307.     *tsector=arranque.BytesSect;
  308.     *sectores=arranque.SectPista; *cabezales=arranque.Caras;
  309.     if ((*sectores==0) || (*cabezales==0)) {
  310.       error++;
  311.       gotoxy (10,5);
  312.       if (sp)
  313.           cputs("Sector de arranque defectuoso");
  314.         else
  315.           cputs("Diskette boot record damaged");
  316.       }
  317.     }
  318.  
  319.   if (!error) {
  320.     *cilindros=arranque.NumSect/(*sectores)/(*cabezales);
  321.     if (*sectores>MAXS) {
  322.       error++;
  323.       gotoxy (4,5);
  324.       if (sp)
  325.           cputs("¡No soportados más de ");
  326.         else
  327.           cputs("Not supported more than ");
  328.       cputs (dec2strq(MAXS));
  329.       if (sp) cputs(" sectores/pista!"); else cputs(" sectors/track!");
  330.       }
  331.     }
  332.  
  333.   return (error==0);
  334. }
  335.  
  336.  
  337. int biosdsk (cmd, drive, head, track, sector, nsects, buffer)
  338. int cmd, drive, head, track, sector, nsects;
  339. unsigned char *buffer;
  340. {
  341.   union REGS r; struct SREGS s;
  342.  
  343.   r.h.ah=cmd; r.h.dl=drive; r.h.dh=head; r.h.ch=track; r.h.cl=sector;
  344.   r.h.al=nsects; s.es=FP_SEG(buffer); r.x.bx=FP_OFF(buffer);
  345.  
  346.   int86x (0x13, &r, &r, &s);
  347.   return (r.h.ah);
  348. }
  349.  
  350.  
  351. int EvaluaBiosIO (operacion, buffer, unidad, cilindros, nsect, cabezales, ts)
  352. unsigned operacion, unidad, cilindros, nsect, cabezales, ts;
  353. char *buffer;
  354. {
  355.   int      cilindro, cabezal, fin_io=0, res, xx, yy;
  356.   unsigned long tini, tfin;
  357.   float    bseg;
  358.  
  359.   if (sp)
  360.       cprintf("(buffer de %4.1f Kb)\n", nsect*ts/1024.);
  361.     else
  362.       cprintf("(%4.1f Kb buffer)\n", nsect*ts/1024.);
  363.  
  364.   xx=5; yy=wherey();
  365.  
  366.   outportb (0x43, 0x36);  /* asegurar que cnt0 usa byte bajo-alto */
  367.   outportb (0x40, 0); outportb (0x40, 0);
  368.  
  369.   res=0;
  370.   for (cilindro=0; cilindro<cilindros; cilindro++)
  371.     for (cabezal=0; cabezal<cabezales; cabezal++) {
  372.     if ((cilindro==1) && (!cabezal)) tini=tiempo();
  373.     if (kbhit()) if (getch()==27) {
  374.       gotoxy (xx, yy); clreol();
  375.       if (sp) cputs("¡Abortado por el usuario!");
  376.         else cputs("Aborted by user!");
  377.       goto aborta_io;
  378.       }
  379.     if (res) {
  380.       gotoxy (xx, yy); clreol();
  381.       if (sp)
  382.           cputs("¡Fallo en el acceso a disco!");
  383.         else
  384.           cputs("Failure on disk access!");
  385.       goto aborta_io;
  386.       }
  387.     gotoxy (xx, yy);
  388.     if (sp) cputs("Cilindro "); else cputs("Cylinder ");
  389.     cputs (dec2strq(cilindro));
  390.     if (sp) cputs(" - Cara "); else cputs(" - Side ");
  391.     cputs (dec2strq(cabezal));
  392.     res=biosdsk (((operacion==WR) && (!cilindro)) ? RD: operacion,
  393.                    unidad, cabezal, cilindro, 1, nsect, buffer);
  394.     }
  395.   tfin=tiempo(); fin_io=1;
  396.  
  397.   bseg=(512L*nsect*(cilindros-1)*cabezales)/((tfin-tini)/1193180.0);
  398.   gotoxy (1, yy);
  399.   if (sp)
  400.       cprintf("  %7.2f seg =%6.2f Kb/seg [%7.0f bits/seg]\n",
  401.              (tfin-tini)/1193180.0, bseg/1024.0, bseg*8);
  402.     else
  403.       cprintf("  %7.2f sec =%6.2f Kb/sec [%7.0f bits/sec]\n",
  404.              (tfin-tini)/1193180.0, bseg/1024.0, bseg*8);
  405.  
  406.   aborta_io:
  407.   return (fin_io);
  408. }
  409.  
  410.  
  411. int EvaluaDosIO (operacion, buffer, unidad, nsect, sectores, tsector)
  412. unsigned operacion, unidad, nsect, sectores, tsector;
  413. char *buffer;
  414. {
  415.   unsigned monto, sects, ssis, sini, ns, stest, fin_io=0, res, xx, yy;
  416.   unsigned long tini, tfin;
  417.   float    bseg;
  418.  
  419.   if (nsect==1) {                   /* disco 2MGUI */
  420.       if (operacion==WR)
  421.           monto=65535L/tsector;
  422.         else
  423.           monto = BMAX / tsector;   /* sectores caben en el buffer */
  424.       sects=stest=sectores*80L/82;  /* no usar primeros 2 cilindros */
  425.       }
  426.     else {                          /* disco estándar */
  427.       monto=nsect;
  428.       sects = stest = sectores - nsect * 4;
  429.       }
  430.  
  431.   if (sp)
  432.       cprintf("(buffer de %4.1f Kb)\n", 1.0*monto*tsector/1024);
  433.     else
  434.       cprintf("(%4.1f Kb buffer)\n", 1.0*monto*tsector/1024);
  435.  
  436.   xx=5; yy=wherey();
  437.  
  438.   outportb (0x43, 0x36);  /* asegurar que cnt0 usa byte bajo-alto */
  439.   outportb (0x40, 0); outportb (0x40, 0);
  440.  
  441.   ssis = sectores - sects;
  442.   sini=res=0;
  443.   while (sects) {
  444.     if (ssis) {
  445.       if (BMAX/tsector < ssis) ns = BMAX/tsector; else ns=ssis;
  446.       }
  447.     else if (monto<sects) ns=monto; else ns=sects;
  448.     if (kbhit()) if (getch()==27) {
  449.       gotoxy (xx, yy); clreol();
  450.       if (sp) cputs("¡Abortado por el usuario!");
  451.         else cputs("Aborted by user!");
  452.       goto aborta_io;
  453.       }
  454.     if (res) {
  455.       gotoxy (xx, yy); clreol();
  456.       if (sp)
  457.           cputs("¡Fallo en el acceso a disco!");
  458.         else
  459.           cputs("Failure on disk access!");
  460.       goto aborta_io;
  461.       }
  462.     gotoxy (xx, yy);
  463.     if (sp) cputs("Sectores "); else cputs("Sectors ");
  464.     cputs (dec5strq(sini));
  465.     if (sp) cputs(" a "); else cputs(" to ");
  466.     cputs (dec5strq(sini+ns-1));
  467.     if ((operacion==RD) || (ssis))
  468.         res = absread  (unidad, ns, sini, buffer);
  469.       else
  470.         res = abswrite (unidad, ns, sini, buffer);
  471.      sini += ns;
  472.      if (ssis) { ssis -= ns; tini=tiempo();} else sects -= ns;
  473.      }
  474.   tfin=tiempo(); fin_io=1;
  475.  
  476.   bseg=(1L*tsector*stest)/((tfin-tini)/1193180.0);
  477.   gotoxy (1, yy);
  478.   if (sp)
  479.       cprintf("  %7.2f seg =%6.2f Kb/seg [%7.0f bits/seg]\n",
  480.              (tfin-tini)/1193180.0, bseg/1024.0, bseg*8);
  481.     else
  482.       cprintf("  %7.2f sec =%6.2f Kb/sec [%7.0f bits/sec]\n",
  483.              (tfin-tini)/1193180.0, bseg/1024.0, bseg*8);
  484.  
  485.   aborta_io:
  486.   return (fin_io);
  487. }
  488.